home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 4
/
FM Towns Free Software Collection 4 - Disc 1.iso
/
t_os
/
wstype
/
source
/
keyin.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-18
|
5KB
|
242 lines
/*** [keyin.c]
*
* キーボード入力 (C)ささがわ
*
* For GNU C Compiler (GCC) Version 1.39
*
***/
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "graph.h"
#include "kyb.h"
#include "mos.h"
#include "keyin.h"
#define KEY_BUFSIZ 255 /* バッファサイズ */
#define KEY_ROLLSPD 8 /* スクロール・スピード 1 2 4 8 */
/* 関数プロトタイプ宣言 */
static void Curonoff(int);
static void bufins(char);
static void bufdel(void);
static void bufbks(void);
static void shift(int, int, int);
static char gputc(int);
/* グローバル変数宣言 */
static char buf[KEY_BUFSIZ + 1]; /* バッファ宣言 */
static int len; /* 文字列の長さ 0 <= x <= KEY_BUFSIZ */
static int cur; /* ビューボックス中のカーソルの位置 0 <= x <= kt->keta - 1 */
static int start; /* バッファ中のビューボックスの位置 0 <= x <= len - cur */
static struct keyin_t *kt; /* 環境構造体 */
/* 初期化関数(グローバル) */
void Keyin_init(struct keyin_t *keyt) {
len = 0;
start = 0;
cur = 0;
kt = keyt;
MOS_disp(0);
EGB_boxf(kt->x, kt->y - 15, kt->x + kt->keta * 8 - 1, kt->y, kt->backC, kt->backC);
Curonoff(1);
MOS_disp(1);
KYB_clrbuf();
}
/* 再表示関数(グローバル) */
void Keyin_redisp(void) {
int i;
MOS_disp(0);
for (i = 0; i < kt->keta; i++)
gputc(i);
Curonoff(1);
MOS_disp(1);
}
/* カーソル移動関数(グローバル) */
int Keyin_cur(int cr) {
if (cr < 0 || kt->keta <= cr)
return -1;
if (cr > len - start)
cr = len - start;
if (cur != cr) {
MOS_disp(0);
Curonoff(0);
cur = cr;
Curonoff(1);
MOS_disp(1);
}
return cur;
}
/***
* メイン関数(グローバル)
* 戻り値 0:正常終了 1:入力完了 -1:中断
***/
int Keyin(void) {
int ret;
unsigned kadr, kcode;
if ((kcode = KYB_read(1, &kadr)) == 0xffff) {
ret = 0;
} else if (kcode == 0x1b) {
ret = -1; /* 中断 */
} else if (kcode == 0x0d) {
buf[len] = '\0';
buf[kt->bufn - 1] = '\0';
strcpy(kt->buf, buf); /* 入力完了 */
ret = 1;
} else {
MOS_disp(0);
Curonoff(0);
if (kcode == 0x1c) { /* [→] */
KYB_clrbuf(); /* カーソルの惰性防止 */
if (start + cur == len || (len == KEY_BUFSIZ && start + cur >= len - 1)) {
/* カーソルが、文字列かバッファの末尾にあるならば */
;
} else if (cur == kt->keta - 1) {
/* カーソルがビューボックスの末尾にあるならば */
start++;
shift(0, kt->keta - 1, -1);
} else {
cur++;
}
} else if (kcode == 0x1d) { /* [←] */
KYB_clrbuf(); /* カーソルの惰性防止 */
if (start + cur == 0) {
/* カーソルがバッファの先頭にあるならば */
;
} else if (start > 0 && cur == 1) {
/* ビューボックスがバッファの先頭を表示しておらず、カーソルが1の位置にあるならば */
start--;
shift(0, kt->keta - 1, 1);
} else {
cur--;
}
} else if (kcode == 0x08) { /* [バックスペース] */
KYB_clrbuf(); /* カーソルの惰性防止 */
if (start + cur == 0) {
/* カーソルがバッファの先頭にあるならば */
;
} else if (start > 0 && cur == 1) {
/* ビューボックスがバッファの先頭を表示しておらず、カーソルが1の位置にあるならば */
bufbks();
start--;
gputc(0);
} else {
bufbks();
shift(--cur, kt->keta - 1, -1);
}
} else if (kcode == 0x7f) { /* [削除] */
KYB_clrbuf(); /* カーソルの惰性防止 */
if (start + cur < len) {
/* カーソルが文字列中にあるならば */
bufdel();
shift(cur, kt->keta - 1, -1);
}
} else if (kcode < 0x100 && !iscntrl(kcode)) {
bufins(kcode);
if (cur == kt->keta - 1) {
/* カーソルがビューボックスの末尾にあるならば */
gputc(cur);
if (len != KEY_BUFSIZ || start + cur < len - 1) {
/* カーソルがバッファの末尾にないならば */
start++;
shift(0, cur, -1);
}
} else {
shift(cur++, kt->keta - 1, 1);
}
}
Curonoff(1);
MOS_disp(1);
ret = 0;
}
return ret;
}
/* カーソル表示・非表示関数 */
static void Curonoff(int sw) {
switch (sw) {
case 0:
gputc(cur);
break;
case 1:
EGB_box(kt->x + 8 * cur, kt->y - 15, kt->x + 8 * cur + 1, kt->y, kt->curC);
break;
}
}
/* 一文字挿入関数 (位置:start + cur) */
static void bufins(char c) {
int i;
for (i = len - 1; i >= start + cur; i--)
buf[i + 1] = buf[i];
buf[start + cur] = c;
len++;
if (len >= KEY_BUFSIZ)
len = KEY_BUFSIZ;
}
/* 一文字削除関数 */
static void bufdel(void) {
int i;
for (i = start + cur + 1; i <= len - 1; i++)
buf[i - 1] = buf[i];
len--;
}
/* バックスペース関数 */
static void bufbks(void) {
int i;
for (i = start + cur; i <= len - 1; i++)
buf[i - 1] = buf[i];
len--;
}
/* 左右スクロール関数 */
static void shift(int from, int to, int dir) {
int i;
if (dir >= 0) {
for (i = 0; i < 8 / KEY_ROLLSPD; i++)
EGB_scrl(0, kt->x + 8 * from, kt->y - 15, kt->x + 8 * to + 7, kt->y, KEY_ROLLSPD, 0);
gputc(from);
} else if (dir < 0) {
for (i = 0; i < 8 / KEY_ROLLSPD; i++)
EGB_scrl(0, kt->x + 8 * from, kt->y - 15, kt->x + 8 * to + 7, kt->y, -KEY_ROLLSPD, 0);
gputc(to);
}
}
/* 一文字表示関数 (k:カーソル位置) */
static char gputc(int k) {
char str[5];
EGB_writeMode(EGB_work, 9);
EGB_color(EGB_work, EGB_COL_BACK, kt->backC);
if (start + k >= len)
str[0] = ' ';
else
str[0] = buf[start + k];
str[1] = 0;
EGB_str(str, kt->x + 8 * k, kt->y, kt->foreC);
EGB_writeMode(EGB_work, 0);
return str[0];
}